package thread;

/**
 * Created with IntelliJ IDEA.
 * ClassName: TestDemo
 * Package: thread
 * Description:
 * User: fzykd
 *
 * @Author: LQH
 * Date: 2023-10-10
 * Time: 17:58
 */

//阻塞队列基于循环队列实现的
class MyBlockQueue {

    int[] arr = new int[1000];
    //首指针
    int head = 0;
    //尾
    int tail = 0;
    //有效数据个数
    int size = 0;

    //实现一个生产者 消费者
    //wait 和 notify实现阻塞 线程通知机制
    Object locker = new Object();

    //定义两个方法 入队 和 出队
    public void push(int val) throws InterruptedException {
        //判断满不满
        if (size == arr.length) {
            synchronized (locker) {
                //满的时候就wait阻塞 等到有元素出队列了来通知唤醒
                locker.wait();
                //阻塞就不往下面执行了 这个方法下面的notify也唤醒不了
            }
        }
        //不满就添加
        arr[tail] = val;
        tail++;
        //判断尾指针的位置
        if (tail >= arr.length) {
            tail = 0;
        }
        //有效个数++
        size++;
        synchronized (locker) {
            locker.notify();
        }
    }

    //出队列
    public int pull() throws InterruptedException {
        //判断空不空
        if (size == 0) {
            synchronized (locker) {
                locker.wait();
            }
        }
        //拿数据返回
        int ret = arr[head];
        head++;
        //判断head的位置是不是到最后了
        if (head == arr.length) {
            head = 0;
        }
        //有效个数--
        size--;
        synchronized (locker) {
            locker.notify();
        }
        return ret;
    }

}


//阻塞队列
public class TestDemo {

    private static MyBlockQueue queue = new MyBlockQueue();

    //创建生成者 消费者案例
    public static void main(String[] args) {
        Thread product = new Thread(() -> {
            int num = 0;
            while (true) {
                System.out.println("生成了: " + num);
                try {
                    queue.push(num);
                    num++;
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
        });
        product.start();

        Thread customer = new Thread(() -> {
            while (true) {
                try {
                    int num = queue.pull();
                    System.out.println("消费了: " + num);
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        customer.start();

    }


    public static void main1(String[] args) throws InterruptedException {
        MyBlockQueue queue = new MyBlockQueue();
        for (int i = 1; i < 1002; i++) {
            queue.push(i);
        }

        System.out.println(queue.pull());
        System.out.println(queue.pull());
    }
}
